﻿using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;

namespace RNA_Libraries
{
  public class Edge : INotifyPropertyChanged
  {
    #region Public interface

    public int L { get; private set; }

    public int ReadsCount { get; private set; }

    public Vertex Start
    {
      get { return m_start; }
      set
      {
        if (m_start != value)
        {
          m_start = value;
          FirePropertyChanged("Start");
        }
      }
    }
    public Vertex End
    {
      get { return m_end; }
      set
      {
        if (m_end != value)
        {
          m_end = value;
          FirePropertyChanged("End");
        }
      }
    }

    public string CommonSeq
    {
      get { return m_comSeq; }
    }

    public Edge()
    {

    }
    public Edge(Vertex start, Vertex end)
    {
      PropertyChanged += RecalculateLabel;
      m_start = start;
      m_end = end;
      FirePropertyChanged("Constructor");
    }

    public Vertex PullEdge()
    {
      return new Vertex(Start + End.FinishSubstring(End.Length - L));
    }

    public int Score(IEnumerable<Vertex> reads, Sequence refSeq)
    {
      var pl = PullEdge();
      var res = (from r in reads
                 where pl.ToString().Contains(r.ToString())
                 select r).ToList();
      ReadsCount = res.Count / 2;
      return L + ReadsCount * 2 - SequenceProcessing.LevenshteinDistance(pl, refSeq) + refSeq.Length - pl.Length;
    }

    #endregion

    #region Implementation

    private Vertex m_start;
    private Vertex m_end;
    private string m_comSeq;

    private void RecalculateLabel(object sender, PropertyChangedEventArgs eArgs)
    {
      if (m_start == null || m_end == null)
      {
        L = -1;
        return;
      }
      L = m_start.EdgeLabel(m_end);
      m_comSeq = m_end.StartSubstring(L);
    }

    #region Implementation of INotifyPropertyChanged

    public event PropertyChangedEventHandler PropertyChanged;

    public void FirePropertyChanged(string propName)
    {
      if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propName));
    }

    #endregion

    #endregion
  }
}
